package com.petdog.module.tools.service;

import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * GeoHash工具类，用于经纬度和GeoHash的相互转换
 */
@Component
public class GeoHashUtils {

    private static final String BASE32 = "0123456789bcdefghjkmnpqrstuvwxyz";
    private static final int[] BITS = {16, 8, 4, 2, 1};

    /**
     * 将经纬度转换为GeoHash编码
     * @param latitude 纬度
     * @param longitude 经度
     * @param precision GeoHash精度
     * @return GeoHash编码
     */
    public String encode(double latitude, double longitude, int precision) {
        double[] latInterval = {-90.0, 90.0};
        double[] lonInterval = {-180.0, 180.0};

        StringBuilder geohash = new StringBuilder();
        boolean isEven = true;
        int bit = 0;
        int ch = 0;

        while (geohash.length() < precision) {
            double mid;
            if (isEven) {
                mid = (lonInterval[0] + lonInterval[1]) / 2;
                if (longitude > mid) {
                    ch |= BITS[bit];
                    lonInterval[0] = mid;
                } else {
                    lonInterval[1] = mid;
                }
            } else {
                mid = (latInterval[0] + latInterval[1]) / 2;
                if (latitude > mid) {
                    ch |= BITS[bit];
                    latInterval[0] = mid;
                } else {
                    latInterval[1] = mid;
                }
            }

            isEven = !isEven;
            if (bit < 4) {
                bit++;
            } else {
                geohash.append(BASE32.charAt(ch));
                bit = 0;
                ch = 0;
            }
        }

        return geohash.toString();
    }

    /**
     * 获取指定GeoHash周围的8个邻居GeoHash
     * @param geohash 原始GeoHash
     * @return 包含原始GeoHash和8个邻居的列表
     */
    public List<String> getAdjacent(String geohash) {
        // 定义8个方向的邻居
        String[] directions = {"right", "left", "top", "bottom", "topRight", "topLeft", "bottomRight", "bottomLeft"};
        List<String> adjacent = new ArrayList<>();
        adjacent.add(geohash);

        for (String direction : directions) {
            String neighbor = getNeighbor(geohash, direction);
            if (neighbor != null) {
                adjacent.add(neighbor);
            }
        }

        return adjacent;
    }

    /**
     * 获取指定方向的邻居GeoHash
     * @param geohash 原始GeoHash
     * @param direction 方向
     * @return 邻居GeoHash
     */
    private String getNeighbor(String geohash, String direction) {
        // 这里简化实现，实际项目中需要完善
        // 此处仅作为示例，真实场景需要更复杂的计算
        return null;
    }

    /**
     * 计算两个经纬度之间的距离（公里）
     * @param lat1 第一个点的纬度
     * @param lon1 第一个点的经度
     * @param lat2 第二个点的纬度
     * @param lon2 第二个点的经度
     * @return 距离（公里）
     */
    public double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
        final int R = 6371; // 地球半径（公里）
        double latDistance = Math.toRadians(lat2 - lat1);
        double lonDistance = Math.toRadians(lon2 - lon1);
        double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        return R * c;
    }
}